package com.lake.hbanner;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.media.ExifInterface;
import android.net.Uri;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;

import com.lake.banner.uitls.LogUtils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import static android.os.Environment.DIRECTORY_PICTURES;

/**
 * 通用工具
 */
public class CommonUtils {

    private static final String TAG = "CommonUtils";
    private static long lastclicked = 0;
    private static final long INTERVAL = 300;

    /**
     * 判断快速点击
     *
     * @return
     */
    public static boolean isFastClick() {
        if (System.currentTimeMillis() - lastclicked < INTERVAL) {
            lastclicked = System.currentTimeMillis();
            return true;
        }
        lastclicked = System.currentTimeMillis();
        return false;
    }


    /**
     * 按图片比较计算放大比例以及锚点位置
     *
     * @param context
     * @param src
     * @param getFaces
     * @return
     */
    public static float[] getBitmapZoomCenter(Context context, Bitmap src, List<List<Double>> getFaces) {
        Log.d(TAG, "getBitmapZoomCenter");
        if (src == null) {
            return null;
        }
        // 获取屏幕宽高（方法1）
        // 获取屏幕密度（方法2）
        DisplayMetrics dm = new DisplayMetrics();
        dm = context.getResources().getDisplayMetrics();
        float density = dm.density; // 屏幕密度（像素比例：0.75/1.0/1.5/2.0）
        int densityDPI = dm.densityDpi; // 屏幕密度（每寸像素：120/160/240/320）
        float xdpi = dm.xdpi;
        float ydpi = dm.ydpi;
        Log.e(TAG, "xdpi=" + xdpi + "; ydpi=" + ydpi);
        Log.e(TAG, "density=" + density + "; densityDPI=" + densityDPI);
        int screenWidth = dm.widthPixels; // 屏幕宽（像素，如：480px）
        int screenHeight = dm.heightPixels; // 屏幕高（像素，如：800px）
        Log.e(TAG, "screenWidth=" + screenWidth + "; screenHeight=" + screenHeight);
        // 图片宽度
        int w = src.getWidth();
        // 图片高度
        int h = src.getHeight();
        // Imageview宽度
        int x = screenWidth;
        // Imageview高度
        int y = screenHeight;
        // 高宽比之差
        int temp = (y / x) - (h / w);
        Log.d(TAG, "temp:" + temp);
        //屏幕面积
        int sc = x * y;
        Log.d(TAG, "屏幕面积:" + sc);

        /**
         * 处理X,Y
         */
        List<Integer> xList = new ArrayList<>();
        List<Integer> yList = new ArrayList<>();
        for (int i = 0; i < getFaces.size(); i++) {
            yList.add((int) (getFaces.get(i).get(1) * h));
            yList.add((int) ((getFaces.get(i).get(1) + getFaces.get(i).get(3)) * h));
            xList.add((int) (getFaces.get(i).get(0) * w));
            xList.add((int) ((getFaces.get(i).get(0) + getFaces.get(i).get(2)) * w));
        }

        Collections.sort(yList);
        Collections.sort(xList);
        for (Integer in : yList) {
            Log.d(TAG, "y = " + in);
        }
        for (Integer in : xList) {
            Log.d(TAG, "x = " + in);
        }
        int xl = ((xList.get(xList.size() - 1) - xList.get(0)) * y) / h;
        int yl = ((yList.get(yList.size() - 1) - yList.get(0)) * x) / w;
        float m = xl * yl;
        Log.d(TAG, "宽：" + xl + "，高 ：" + yl + " ,面积：" + m);
        /**
         * 判断高宽比例，如果目标高宽比例大于原图，则原图高度不变，宽度为(w1 = (h * x) / y)拉伸
         * 画布宽高(w1,h),在原图的((w - w1) / 2, 0)位置进行切割
         */
        if (temp > 0) {
            // 计算
            int h1 = (h * x) / w;
            int offset = (y - h1) / 2;
            int tx = (xList.get(0) + xList.get(xList.size() - 1)) / 2;
            int ty = (yList.get(0) + yList.get(yList.size() - 1)) / 2;
            Log.d(TAG, "tx:" + tx + ",ty:" + ty + ",offset:" + offset);
            int fx = (tx * x) / w;
            int fy = (ty * x) / w + offset;
            float scale = 1.1f;
            if (xl < (0.7 * x)) {
                scale = (float) x / xl;
            }
            //原图回收
            float[] re = new float[3];
            re[0] = fx;
            re[1] = fy;
            re[2] = scale;
            return re;
        } else {
            /**
             * 如果目标高宽比小于原图，则原图宽度不变，高度为(h1 = (y * w) / x),
             * 画布宽高(w, h1), 原图切割点(0, (h - h1) / 2)
             */
            // 计算画布高度
            int w1 = (w * y) / h;
            int offset = (x - w1) / 2;
            int tx = (xList.get(0) + xList.get(xList.size() - 1)) / 2;
            int ty = (yList.get(0) + yList.get(yList.size() - 1)) / 2;
            Log.d(TAG, "tx:" + tx + ",ty:" + ty + ",offset:" + offset);
            int fx = (tx * y) / h + offset;
            int fy = (ty * y) / h;
            Log.d(TAG, "fx:" + fx + ",fy:" + fy + ",offset:" + offset);
            float scale = 1.1f;
            if (yl < (0.7 * y)) {
                scale = (float) y / yl;
            }
            Log.d(TAG, "fx:" + fx + ",fy:" + fy + ",offset:" + offset + ",scale:" + scale);
            float[] re = new float[3];
            re[0] = fx;
            re[1] = fy;
            re[2] = scale;
            return re;
        }
    }


    /**
     * 以CenterCrop方式resize图片
     *
     * @param src  原始图片
     * @return
     */
    public static Bitmap resizeBitmapByCenterCrop(Context context, Bitmap src, List<List<Double>> getFaces) {
        Log.d(TAG, "resizeBitmapByCenterCrop");
        if (src == null) {
            return null;
        }
        // 获取屏幕宽高（方法1）
        // 获取屏幕密度（方法2）
        DisplayMetrics dm = new DisplayMetrics();
        dm = context.getResources().getDisplayMetrics();
        float density = dm.density; // 屏幕密度（像素比例：0.75/1.0/1.5/2.0）
        int densityDPI = dm.densityDpi; // 屏幕密度（每寸像素：120/160/240/320）
        float xdpi = dm.xdpi;
        float ydpi = dm.ydpi;
        LogUtils.e(TAG, "xdpi=" + xdpi + "; ydpi=" + ydpi);
        LogUtils.e(TAG, "density=" + density + "; densityDPI=" + densityDPI);
        int screenWidth = dm.widthPixels; // 屏幕宽（像素，如：480px）
        int screenHeight = dm.heightPixels; // 屏幕高（像素，如：800px）
        LogUtils.e(TAG, "screenWidth=" + screenWidth + "; screenHeight=" + screenHeight);

        // 图片宽度
        int w = src.getWidth();
        // 图片高度
        int h = src.getHeight();
        LogUtils.d(TAG, "图片宽高：" + w + "*" + h);
        // Imageview宽度
        int x = screenWidth;
        // Imageview高度
        int y = screenHeight;
        // 高宽比之差
        int temp = (y / x) - (h / w);
        LogUtils.d(TAG, "temp:" + temp);
        /**
         * 处理X,Y
         */
        List<Integer> integerList = new ArrayList<>();
        for (int i = 0; i < getFaces.size(); i++) {
            integerList.add((int) (getFaces.get(i).get(1) * h));
            integerList.add((int) ((getFaces.get(i).get(1) + getFaces.get(i).get(3)) * h));
        }
        Collections.sort(integerList);
        for (Integer in : integerList) {
            LogUtils.d(TAG, "y = " + in);
        }
        /**
         * 判断高宽比例，如果目标高宽比例大于原图，则原图高度不变，宽度为(w1 = (h * x) / y)拉伸
         * 画布宽高(w1,h),在原图的((w - w1) / 2, 0)位置进行切割
         */
        if (temp > 0) {
            // 计算画布宽度
            int w1 = (h * x) / y;
            // 创建一个指定高宽的图片
            Bitmap newb = Bitmap.createBitmap(src, (w - w1) / 2, 0, w1, h);
            //原图回收
            return newb;
        } else {
            /**
             * 如果目标高宽比小于原图，则原图宽度不变，高度为(h1 = (y * w) / x),
             * 画布宽高(w, h1), 原图切割点(0, (h - h1) / 2)
             */
            // 计算画布高度
            int h1 = (y * w) / x;
            int off = integerList.get(integerList.size() - 1) - integerList.get(0);
            int nh = toOffSet(off, w, x);
            LogUtils.d(TAG, "画布高度：" + h1 + ",实际所需高度：" + nh);
            int y0 = toOffSet(integerList.get(0), w, x);

            LogUtils.d(TAG, "第一个像素点位置：y0 = " + y0);
            if (nh > h1) {
                LogUtils.d(TAG, "画布高度 < 实际所需高度  ----> 生成图片高度为实际所需高度");
                Bitmap newb = Bitmap.createBitmap(src, 0, y0 - 20 > 0 ? y0 - 20 : y0, w, nh);
                return newb;
            } else {
                LogUtils.d(TAG, "画布高度 > 实际所需高度  ----> 生成图片高度为画布高度");
                int offset = (h1 - nh) / 2;
                LogUtils.d(TAG, "offset:" + offset);
                LogUtils.d(TAG, "h-y0=" + (h - y0) + "----h-h1=" + (h - h1));
                if (h - y0 < h1) {
                    Bitmap newb = Bitmap.createBitmap(src, 0, h - h1, w, h1);
                    return newb;
                } else {
                    Bitmap newb = Bitmap.createBitmap(src, 0, y0 - offset > 0 ? y0 - offset : y0, w, h1);
                    return newb;
                }
            }
            // 创建一个指定高宽的图片(h - h1) / 2
        }
    }


    private static int toOffSet(int src, int w, int x) {
        if (w < x) {
            return src;
        } else {
            return (src * w) / x;
        }
    }

    /*
     *
     * @Title: bitmapRotation
     * @Description: 图片旋转
     * @param bm
     * @param orientationDegree
     * @return Bitmap
     * @throws
     */
    public Bitmap bitmapRotation(Bitmap bm, final int orientationDegree) {

        Matrix m = new Matrix();
        m.setRotate(orientationDegree, (float) bm.getWidth() / 2,
                (float) bm.getHeight() / 2);
        float targetX, targetY;
        if (orientationDegree == 90) {
            targetX = bm.getHeight();
            targetY = 0;
        } else if (orientationDegree == 270) {
            targetX = 0;
            targetY = bm.getWidth();
        } else {
            targetX = bm.getHeight();
            targetY = bm.getWidth();
        }

        final float[] values = new float[9];
        m.getValues(values);

        float x1 = values[Matrix.MTRANS_X];
        float y1 = values[Matrix.MTRANS_Y];

        m.postTranslate(targetX - x1, targetY - y1);

        Bitmap bm1 = Bitmap.createBitmap(bm.getHeight(), bm.getWidth(),
                Bitmap.Config.ARGB_8888);

        Paint paint = new Paint();
        Canvas canvas = new Canvas(bm1);
        canvas.drawBitmap(bm, m, paint);

        return bm1;
    }


    public static synchronized String createtFileName(String suffix) {
        java.util.Date dt = new java.util.Date(System.currentTimeMillis());
        SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        String fileName = fmt.format(dt);
        fileName = fileName + suffix; //extension, you can change it.
        return fileName;
    }

    /**
     * 增加自定义名称
     *
     * @param suffix
     * @param name
     * @return
     */
    public static synchronized String createtFileName(String suffix, String name) {
        String fileName = name + suffix; //extension, you can change it.
        return fileName;
    }


    //将字节数组转换为16进制字符串
    public static String BinaryToHexString(byte[] bytes) {
        String hexStr = "0123456789ABCDEF";
        String result = "";
        String hex = "";
        for (byte b : bytes) {
            hex = String.valueOf(hexStr.charAt((b & 0xF0) >> 4));
            hex += String.valueOf(hexStr.charAt(b & 0x0F));
            result += hex + " ";
        }
        return result;
    }

    /*
     *Bitmap转byte数组
     */
    public static byte[] BitmapToBytes(Bitmap bitmap) {
        int bytes = bitmap.getByteCount();
        ByteBuffer buffer = ByteBuffer.allocate(bytes); // Create a new buffer
        bitmap.copyPixelsToBuffer(buffer); // Move the byte data to the buffer
        return buffer.array();
    }

    /*
     *byte数组转Bitmap
     */
    public static Bitmap BytesToBitmap(byte[] bis) {
        return BitmapFactory.decodeByteArray(bis, 0, bis.length);
    }

    public static File saveToLocal(Bitmap bitmap, Context context) {
        if (null == bitmap) return null;
        String temp = CommonUtils.createtFileName(".png");
        File dcimFile = context.getExternalFilesDir(DIRECTORY_PICTURES);
        File tempFile = new File(dcimFile, temp);
        LogUtils.d(TAG, "tempFile:" + tempFile.getPath());
        try {
            FileOutputStream fos = new FileOutputStream(tempFile);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
            fos.flush();
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            tempFile = null;
        } catch (IOException e) {
            e.printStackTrace();
            tempFile = null;
        }
        return tempFile;
    }

    public static File saveToLocal(Bitmap bitmap, Context context, String name) {
        if (null == bitmap) return null;
        String temp = CommonUtils.createtFileName(".png", name);
        File dcimFile = context.getExternalFilesDir(DIRECTORY_PICTURES);
        File tempFile = new File(dcimFile, temp);
        try {
            FileOutputStream fos = new FileOutputStream(tempFile);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
            fos.flush();
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            tempFile = null;
        } catch (IOException e) {
            e.printStackTrace();
            tempFile = null;
        }
        return tempFile;
    }

    public static Bitmap ImageSizeCompress(Uri uri, Context context) {
        InputStream Stream = null;
        InputStream inputStream = null;
        try {
            //根据uri获取图片的流
            inputStream = context.getContentResolver().openInputStream(uri);
            BitmapFactory.Options options = new BitmapFactory.Options();
            //options的in系列的设置了，injustdecodebouond只解析图片的大小，而不加载到内存中去
            options.inJustDecodeBounds = true;
            //1.如果通过options.outHeight获取图片的宽高，就必须通过decodestream解析同options赋值
            //否则options.outheight获取不到宽高
            BitmapFactory.decodeStream(inputStream, null, options);
            //2.通过 btm.getHeight()获取图片的宽高就不需要1的解析，我这里采取第一张方式
//            Bitmap btm = BitmapFactory.decodeStream(inputStream);
            //以屏幕的宽高进行压缩
            DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
            int heightPixels = displayMetrics.heightPixels;
            int widthPixels = displayMetrics.widthPixels;
            //获取图片的宽高
            int outHeight = options.outHeight;
            int outWidth = options.outWidth;
            //heightPixels就是要压缩后的图片高度，宽度也一样
            int a = (int) Math.ceil((outHeight / (float) heightPixels));
            int b = (int) Math.ceil(outWidth / (float) widthPixels);
            //比例计算,一般是图片比较大的情况下进行压缩
            int max = Math.max(a, b);
            if (max > 1) {
                options.inSampleSize = max;
            }
            //解析到内存中去
            options.inJustDecodeBounds = false;
//            根据uri重新获取流，inputstream在解析中发生改变了
            Stream = context.getContentResolver().openInputStream(uri);
            Bitmap bitmap = BitmapFactory.decodeStream(Stream, null, options);
            return bitmap;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (Stream != null) {
                    Stream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return null;
    }


    /**
     * 压缩Bitmap的大小
     * Compress Bitmap size
     *
     * @param imagePath     图片文件路径
     * @param requestWidth  压缩到想要的宽度
     * @param requestHeight 压缩到想要的高度
     * @return
     */
    public static Bitmap decodeBitmapFromFile(String imagePath, int requestWidth, int requestHeight) {
        try {
            if (!TextUtils.isEmpty(imagePath)) {
                if (requestWidth <= 0 || requestHeight <= 0) {
                    BitmapFactory.Options o2 = new BitmapFactory.Options();
                    o2.inSampleSize = 1;
                    Bitmap bitmap = BitmapFactory.decodeFile(imagePath, o2);
                    return rotateImage(bitmap, imagePath);
                }
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inJustDecodeBounds = true;//不加载图片到内存，仅获得图片宽高
                BitmapFactory.decodeFile(imagePath, options);
                if (options.outHeight == -1 || options.outWidth == -1) {
                    try {
                        ExifInterface exifInterface = new ExifInterface(imagePath);
                        int height = exifInterface.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, ExifInterface.ORIENTATION_NORMAL);//获取图片的高度
                        int width = exifInterface.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, ExifInterface.ORIENTATION_NORMAL);//获取图片的宽度
                        options.outWidth = width;
                        options.outHeight = height;
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                options.inSampleSize = calculateInSampleSize(options, requestWidth, requestHeight); //计算获取新的采样率
                options.inJustDecodeBounds = false;
                return rotateImage(BitmapFactory.decodeFile(imagePath, options), imagePath);

            } else {
                return null;
            }
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }

    }

    public static Bitmap decodeBitmapFromFile(Context context, int resId, int requestWidth, int requestHeight) {
        if (resId != -1) {
            if (requestWidth <= 0 || requestHeight <= 0) {
                BitmapFactory.Options o2 = new BitmapFactory.Options();
                o2.inSampleSize = 1;
                Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resId, o2);
                return bitmap;
            }
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;//不加载图片到内存，仅获得图片宽高
            BitmapFactory.decodeResource(context.getResources(), resId, options);
            if (options.outHeight == -1 || options.outWidth == -1) {
                Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resId);
                int height = bitmap.getHeight();//获取图片的高度
                int width = bitmap.getWidth();//获取图片的宽度
                options.outWidth = width;
                options.outHeight = height;
            }
            options.inSampleSize = calculateInSampleSize(options, requestWidth, requestHeight); //计算获取新的采样率
            options.inJustDecodeBounds = false;
            return BitmapFactory.decodeResource(context.getResources(), resId, options);

        } else {
            return null;
        }
    }

    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {

            final int halfHeight = height / 2;
            final int halfWidth = width / 2;
            while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }

            long totalPixels = width * height / inSampleSize;

            final long totalReqPixelsCap = reqWidth * reqHeight * 2;

            while (totalPixels > totalReqPixelsCap) {
                inSampleSize *= 2;
                totalPixels /= 2;
            }
        }
        return inSampleSize;
    }

    public static Bitmap rotateBitmap(Bitmap origin, float alpha) {
        if (origin == null) {
            return null;
        }
        int width = origin.getWidth();
        int height = origin.getHeight();
        Matrix matrix = new Matrix();
        matrix.setRotate(alpha);
        // 围绕原地进行旋转
        Bitmap newBM = Bitmap.createBitmap(origin, 0, 0, width, height, matrix, false);
        if (newBM.equals(origin)) {
            return newBM;
        }
        origin.recycle();
        return newBM;
    }


    public static Bitmap rotateImage(Bitmap bitmap, String path) throws IOException {
        if (bitmap == null) return null;
        if (TextUtils.isEmpty(path)) return null;
        int rotate = 0;
        ExifInterface exif;
        exif = new ExifInterface(path);
        int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                ExifInterface.ORIENTATION_NORMAL);
        switch (orientation) {
            case ExifInterface.ORIENTATION_ROTATE_270:
                rotate = 270;
                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                rotate = 180;
                break;
            case ExifInterface.ORIENTATION_ROTATE_90:
                rotate = 90;
                break;
        }
        if (rotate == 0) return bitmap;
        Matrix matrix = new Matrix();
        matrix.postRotate(rotate);
        return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
                bitmap.getHeight(), matrix, true);
    }

}
